package utils

import (
	"html"
	"regexp"
	"strings"
	"unicode/utf8"
)

// InputValidator 输入验证器
type InputValidator struct{}

// NewInputValidator 创建新的输入验证器
func NewInputValidator() *InputValidator {
	return &InputValidator{}
}

// SanitizeString 清理字符串，防止XSS攻击
func (v *InputValidator) SanitizeString(input string) string {
	// HTML转义
	input = html.EscapeString(input)
	// 移除危险字符
	input = strings.ReplaceAll(input, "<script", "&lt;script")
	input = strings.ReplaceAll(input, "</script>", "&lt;/script&gt;")
	return strings.TrimSpace(input)
}

// ValidateEmail 验证邮箱格式
func (v *InputValidator) ValidateEmail(email string) bool {
	if len(email) == 0 {
		return false
	}
	emailRegex := regexp.MustCompile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`)
	return emailRegex.MatchString(email)
}

// ValidatePhone 验证手机号格式
func (v *InputValidator) ValidatePhone(phone string) bool {
	if len(phone) == 0 {
		return false
	}
	phoneRegex := regexp.MustCompile(`^1[3-9]\d{9}$`)
	return phoneRegex.MatchString(phone)
}

// ValidateStudentNumber 验证学号格式
func (v *InputValidator) ValidateStudentNumber(sn string) bool {
	if len(sn) == 0 {
		return false
	}
	// 假设学号为8-12位数字和字母组合
	snRegex := regexp.MustCompile(`^[A-Za-z0-9]{8,12}$`)
	return snRegex.MatchString(sn)
}

// ValidatePassword 验证密码强度
func (v *InputValidator) ValidatePassword(password string) (bool, string) {
	if len(password) < 6 {
		return false, "密码长度至少6位"
	}
	if len(password) > 128 {
		return false, "密码长度不能超过128位"
	}

	// 检查是否包含基本字符要求
	hasLetter := regexp.MustCompile(`[a-zA-Z]`).MatchString(password)
	hasNumber := regexp.MustCompile(`[0-9]`).MatchString(password)

	if !hasLetter || !hasNumber {
		return false, "密码必须包含字母和数字"
	}

	return true, ""
}

// ValidateStringLength 验证字符串长度
func (v *InputValidator) ValidateStringLength(input string, minLen, maxLen int) bool {
	length := utf8.RuneCountInString(input)
	return length >= minLen && length <= maxLen
}

// IsSQLInjectionAttempt 检测潜在的SQL注入尝试
func (v *InputValidator) IsSQLInjectionAttempt(input string) bool {
	input = strings.ToLower(input)
	sqlKeywords := []string{
		"select", "insert", "update", "delete", "drop", "create", "alter",
		"union", "script", "exec", "declare", "--", "/*", "*/", ";",
		"'", "\"", "xp_", "sp_",
	}

	for _, keyword := range sqlKeywords {
		if strings.Contains(input, keyword) {
			return true
		}
	}
	return false
}

// ValidateUploadFileName 验证上传文件名
func (v *InputValidator) ValidateUploadFileName(filename string) bool {
	if len(filename) == 0 {
		return false
	}

	// 检查文件名长度
	if len(filename) > 255 {
		return false
	}

	// 检查是否包含危险字符
	dangerousChars := []string{"../", "..\\", "<", ">", ":", "\"", "|", "?", "*"}
	for _, char := range dangerousChars {
		if strings.Contains(filename, char) {
			return false
		}
	}

	// 验证文件扩展名
	allowedExts := []string{".jpg", ".jpeg", ".png", ".gif", ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".txt"}
	filename = strings.ToLower(filename)
	for _, ext := range allowedExts {
		if strings.HasSuffix(filename, ext) {
			return true
		}
	}

	return false
}

// RemoveDangerousChars 移除危险字符
func (v *InputValidator) RemoveDangerousChars(input string) string {
	// 移除控制字符
	input = regexp.MustCompile(`[\x00-\x1f\x7f]`).ReplaceAllString(input, "")
	// 移除SQL相关的危险字符组合
	input = regexp.MustCompile(`(--|/\*|\*/|;|'|")`).ReplaceAllString(input, "")
	return input
}
